package com.erp.wallet.service.impl;

import cn.hutool.core.bean.BeanUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.erp.wallet.domain.bo.ErpSellerStoreWalletBo;
import com.erp.wallet.domain.bo.ErpSellerStoreWalletLogBo;
import com.erp.wallet.domain.vo.ErpSellerStoreWalletVo;
import com.erp.wallet.mapper.ErpSellerStoreWalletMapper;
import com.erp.wallet.service.IErpSellerStoreWalletLogService;
import com.erp.wallet.service.IErpSellerStoreWalletService;
import com.ruoyi.common.core.domain.PageQuery;
import com.ruoyi.common.core.domain.R;
import com.ruoyi.common.core.enums.ExpenseType;
import com.ruoyi.common.core.utils.oldUtils.StringUtils;
import com.ruoyi.common.core.web.oldPage.TableDataInfo;
import com.ruoyi.wallet.api.domain.ErpSellerStoreWallet;
import lombok.RequiredArgsConstructor;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.math.BigDecimal;
import java.util.Collection;
import java.util.List;
import java.util.Map;

/**
 * erp用户钱包Service业务层处理
 *
 * @author erp
 * @date 2023-05-09
 */
@RequiredArgsConstructor
@Service
public class ErpSellerStoreWalletServiceImpl implements IErpSellerStoreWalletService {

	private final ErpSellerStoreWalletMapper baseMapper;
	private final IErpSellerStoreWalletLogService iErpSellerStoreWalletLogService;

	/**
	 * 查询erp用户钱包
	 */
	@Override
	public ErpSellerStoreWalletVo queryById(Long id) {
		return baseMapper.selectVoById(id);
	}

	/**
	 * 查询erp用户钱包列表
	 */
	@Override
	public TableDataInfo<ErpSellerStoreWalletVo> queryPageList(ErpSellerStoreWalletBo bo, PageQuery pageQuery) {
		LambdaQueryWrapper<ErpSellerStoreWallet> lqw = buildQueryWrapper(bo);
		Page<ErpSellerStoreWalletVo> result = baseMapper.selectVoPage(pageQuery.build(), lqw);
		return TableDataInfo.build(result);
	}

	/**
	 * 查询erp用户钱包列表
	 */
	@Override
	public List<ErpSellerStoreWalletVo> queryList(ErpSellerStoreWalletBo bo) {
		LambdaQueryWrapper<ErpSellerStoreWallet> lqw = buildQueryWrapper(bo);
		return baseMapper.selectVoList(lqw);
	}

	private LambdaQueryWrapper<ErpSellerStoreWallet> buildQueryWrapper(ErpSellerStoreWalletBo bo) {
		Map<String, Object> params = bo.getParams();
		LambdaQueryWrapper<ErpSellerStoreWallet> lqw = Wrappers.lambdaQuery();
		lqw.eq(bo.getId() != null, ErpSellerStoreWallet::getId, bo.getId());
		lqw.eq(StringUtils.isNotBlank(bo.getSellerId()), ErpSellerStoreWallet::getSellerId, bo.getSellerId());
		lqw.eq(bo.getMoney() != null, ErpSellerStoreWallet::getMoney, bo.getMoney());
		lqw.eq(bo.getFreeze() != null, ErpSellerStoreWallet::getFreeze, bo.getFreeze());
		return lqw;
	}

	/**
	 * 新增erp用户钱包
	 */
	@Override
	public Boolean insertByBo(ErpSellerStoreWalletBo bo) {
		ErpSellerStoreWallet add = BeanUtil.toBean(bo, ErpSellerStoreWallet.class);
		validEntityBeforeSave(add);
		boolean flag = baseMapper.insert(add) > 0;
		if (flag) {
			bo.setId(add.getId());
		}
		return flag;
	}

	/**
	 * 修改erp用户钱包
	 */
	@Override
	public Boolean updateByBo(ErpSellerStoreWalletBo bo) {
		ErpSellerStoreWallet update = BeanUtil.toBean(bo, ErpSellerStoreWallet.class);
		validEntityBeforeSave(update);
		return baseMapper.updateById(update) > 0;
	}

	/**
	 * 保存前的数据校验
	 */
	private void validEntityBeforeSave(ErpSellerStoreWallet entity) {
		// TODO 做一些数据校验,如唯一约束
	}

	/**
	 * 批量删除erp用户钱包
	 */
	@Override
	public Boolean deleteWithValidByIds(Collection<Long> ids, Boolean isValid) {
		if (isValid) {
			// TODO 做一些业务上的校验,判断是否需要校验
		}
		return baseMapper.deleteBatchIds(ids) > 0;
	}

	/**
	 * 初始化钱包
	 * 
	 * @param userId 用户id
	 */
	@Override
	public ErpSellerStoreWallet init(Long userId) {
		LambdaQueryWrapper<ErpSellerStoreWallet> lqw = new LambdaQueryWrapper<ErpSellerStoreWallet>();
		lqw.eq(ErpSellerStoreWallet::getSellerId, userId);
		lqw.last(" limit 1 ");
		ErpSellerStoreWallet wallet = baseMapper.selectOne(lqw);
		if (wallet == null) {
			wallet = new ErpSellerStoreWallet();
			wallet.setMoney(BigDecimal.ZERO);
			wallet.setFreeze(BigDecimal.ZERO);
			wallet.setSellerId(userId + "");
			wallet.setRevision("0");
			baseMapper.insert(wallet);
		}
		return wallet;
	}

	@Override
	public ErpSellerStoreWallet findBySellerId(Long sellerId) {

		LambdaQueryWrapper<ErpSellerStoreWallet> lqw = new LambdaQueryWrapper<ErpSellerStoreWallet>();
		lqw.eq(ErpSellerStoreWallet::getSellerId, sellerId);
		lqw.last(" limit 1 ");
		ErpSellerStoreWallet wallet = baseMapper.selectOne(lqw);
		if (wallet == null) {
			wallet = init(sellerId);
		}
		return wallet;
	}

	/**
	 * 修改钱包的金额
	 * 
	 * @return
	 */
	@Transactional
	@Override
	public R<Object> updateWallet(Integer flowType, Integer expenseType, Integer payType, BigDecimal money,
                                  Long sellerId, String orderNo, String remark) {

		// 获取用户的钱包
		ErpSellerStoreWallet wallet = findBySellerId(sellerId);
		if (wallet == null) {
			wallet = init(sellerId);
		}
		// 获取余额
		BigDecimal yue = wallet.getMoney();
		// 获取冻结金额
		BigDecimal freeze = wallet.getFreeze();
		if (flowType.equals(0)) { // 入款+
			yue = yue.add(money);
		} else if (flowType.equals(1)) { // 扣款-
			if(expenseType.equals(ExpenseType.EVALUATION.getCode())) {
				
			}else {
				// 判断金额
				if (yue.compareTo(money) == -1) { // 大于等于
					return R.fail("余额不足");
				}
			}

			yue = yue.subtract(money);
		} else if (flowType.equals(2)) { // 冻结
			freeze = freeze.add(money);
			yue = yue.subtract(money);
		} else if (flowType.equals(3)) { // 解冻
			freeze = freeze.subtract(money);
			yue = yue.add(money);
		}
		// 修改钱包信息
		wallet.setMoney(yue);
		wallet.setFreeze(freeze);
		int updateById = baseMapper.updateById(wallet);

		// 保存钱包日志
		ErpSellerStoreWalletLogBo log = new ErpSellerStoreWalletLogBo();
		log.setFlowType(flowType);
		log.setExpenseType(expenseType);
		log.setPayType(payType);
		log.setOrderNumber(orderNo);
		log.setMoney(money);
		log.setSellerId(sellerId);
		log.setRemark(remark);
		Boolean insertByBo = iErpSellerStoreWalletLogService.insertByBo(log);
		if (updateById > 0 && insertByBo)
			return R.ok();
		else
			return R.fail();
	}
}
